#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
/*
 * Zenlayer.com Inc.
 * Copyright (c) 2014-2020 All Rights Reserved.
 */
package ${package}.${artifactId}.common;

import com.fasterxml.jackson.annotation.JsonValue;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Objects;

/**
 * @author yangshen
 * @date 2019-08-30 11:04:41
 * @version ${symbol_dollar} Id: BaseEnum.java, v 0.1  yangshen Exp ${symbol_dollar}
 */
public interface BaseEnum<T extends Serializable> {
    /**
     * 功能描述 通过枚举的val（数据库值）逆向查找枚举对象
     * @param val 枚举值
     * @param eClz 需要查找的枚举类
     * @param <E> 枚举类
     * @param <T> val的类型
     * @return 枚举对象，找不到返回null
     **/
    static <E extends Enum<E> & BaseEnum<T>, T extends Serializable> E ofValue(T val, Class<E> eClz) {
        E[] constants = eClz.getEnumConstants();
        for (E aEnum : constants) {
            if (Objects.equals(aEnum.getVal(), val)) {
                return aEnum;
            }
        }
        return null;
    }

    /**
     * 根据String val 获取 枚举
     * @param val 枚举值
     * @param eClz 需要查找的枚举类
     * @param <E> 枚举类
     * @return 枚举对象，找不到返回null
     */
    //static <E extends BaseEnum<String>> E ofValue(String val, Class<E> eClz) {
    //    E[] constants = eClz.getEnumConstants();
    //    for (E aEnum : constants) {
    //        if (Objects.equals(String.valueOf(aEnum.getVal()), val)) {
    //            return aEnum;
    //        }
    //    }
    //    return null;
    //}

    /**
     * 根据 枚举code 获取  当前枚举
     * @param code
     * @param eClz
     * @param <E>
     * @return
     */
    static <E extends BaseEnum<Integer>> E ofCode(Integer code, Class<E> eClz) {
        E[] constants = eClz.getEnumConstants();
        for (E aEnum : constants) {
            if (Objects.equals(aEnum.getCode(), code)) {
                return aEnum;
            }
        }
        return null;
    }

    /**
     * 根据枚举信息，获取 当前枚举
     * @param msg
     * @param eClz
     * @param <E>
     * @return
     */
    static <E extends BaseEnum<String>> E ofMsg(String msg, Class<E> eClz) {
        E[] constants = eClz.getEnumConstants();
        for (E aEnum : constants) {
            if (Objects.equals(aEnum.getMsg(), msg)) {
                return aEnum;
            }
        }
        return null;
    }

    public static <E extends Enum<?> & BaseEnum<E>> E codeOf(Class<E> enumClass, int code) {
        E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (e.getCode() == code) {
                return e;
            }
        }
        return null;
    }

    public static <E extends Enum<?>> boolean isMember(String code, Class<E> enumClass) {

        E[] enumConstants = enumClass.getEnumConstants();
        for (E e : enumConstants) {
            if (StringUtils.equals(e.name(), code)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 功能描述 获取枚举值，直接转发至IEnum<T>接口的方法
     * 主要提供给jackson用来转换枚举对象
     * @return 枚举值
     **/
    @JsonValue
    default T getVal() {
        return getValue();
    }

    /**
     * 接口方法需要实现
     * @return
     */
    T getValue();

    /**
     * 接口方法需要实现
     * @return
     */
    Integer getCode();

    /**
     * 接口方法需要实现
     * @return
     */
    T getMsg();
}
